<template>
    <jb-crud-page
        ref="pageRef"
        search-url="/api/admin/permission/datas"
        :pager="false"
        :edit-component="PermissionEdit"
        @after-submit="pageRef?.loadData()"
        @before-search="beforeSearch"
        @after-search="handleTableData($event)"
    >
        <template #title>
            <jb-icon
                icon="icon-park-outline:permissions"
                class="va--3px inline text-20px"
            ></jb-icon>
            <span class="ml-8px">系统资源权限管理</span>
            <jb-btn
                :icon="Icons.EXPAND"
                text
                class="ml-24px"
                type="success"
                @click="tableRef?.setAllTreeExpand(true)"
            >
                展开
            </jb-btn>
            <n-divider vertical />
            <jb-btn
                :icon="Icons.SHRINK"
                text
                type="warning"
                @click="tableRef?.clearTreeExpand()"
            >
                收起
            </jb-btn>
        </template>
        <template #conditions-form>
            <n-input
                v-model:value="filterForm.keywords"
                type="text"
                clearable
                placeholder="请输入关键字进行过滤"
            />
            <jb-select
                v-model:value="filterForm.moduleId"
                class="w-130px"
                clearable
                url="/api/admin/modules"
            ></jb-select>
        </template>
        <template #opt>
            <n-button-group>
                <jb-btn
                    ghost
                    :icon="Icons.ADD"
                    type="primary"
                    @click="pageRef?.showEditModal('添加权限资源')"
                    >新增</jb-btn
                >
                <jb-btn
                    ghost
                    type="warning"
                    :icon="Icons.REFRESH"
                    @click="pageRef?.loadData()"
                >
                    刷新</jb-btn
                >
                <jb-btn
                    :ghost="!dragable"
                    color="#dd6e6e"
                    :icon="Icons.DRAG"
                    @click="dragable = !dragable"
                >
                    {{ dragable ? '关闭' : '开启' }}拖拽排序</jb-btn
                >
            </n-button-group>
        </template>
        <template #default>
            <jb-table
                ref="tableRef"
                :tree-config="{
                    showLine: true,
                    childrenField: 'items',
                    reserve: true,
                    expandAll: true,
                    rowField: 'id'
                }"
                :loading="loading"
                :column-config="{ useKey: true }"
                :data="showData"
                :dragable="dragable"
                rank-field="sortRank"
                @drag-end="handleDragEnd"
            >
                <jb-column
                    field="name"
                    title="资源"
                    tree-node
                    type="html"
                    align="left"
                    min-width="160"
                    header-align="center"
                    fixed="left"
                ></jb-column>
                <jb-column field="level" title="级别" width="80" fixed="left">
                    <template #default="{ row }">{{ row?.permissionLevel }}级</template>
                </jb-column>
                <jb-column field="ofModuleName" title="模块" min-width="180"></jb-column>
                <jb-column title="打开类型" width="140">
                    <template #default="{ row }">
                        <span :class="`opentype opentype_${row.openType}`">{{
                            row?.openTypeName
                        }}</span>
                    </template>
                </jb-column>
                <jb-column title="资源类型" width="100">
                    <template #default="{ row }">
                        <n-tag v-if="row.isMenu" type="primary"> 菜单 </n-tag>
                        <n-tag v-else type="error"> 非菜单 </n-tag>
                    </template>
                </jb-column>
                <jb-column
                    field="url"
                    title="URL"
                    min-width="150"
                    type="html"
                ></jb-column>
                <jb-column
                    type="html"
                    field="permissionKey"
                    title="KEY"
                    min-width="150"
                ></jb-column>
                <jb-column
                    field="isSystemAdminDefault"
                    title="超管默认"
                    width="80"
                    fixed="right"
                >
                    <template #default="{ row }">
                        <jb-switch
                            v-model:value="row.isSystemAdminDefault"
                            confirm="确定切换此状态？"
                            :url="`/api/admin/permission/toggleIsSystemAdminDefault/${row.id}`"
                            @change="pageRef?.loadData()"
                        ></jb-switch>
                    </template>
                </jb-column>
                <jb-column title="操作" fixed="right" width="140">
                    <template #default="{ row }">
                        <jb-btn
                            tip-text="添加子权限"
                            :icon="Icons.ADD"
                            secondary
                            circle
                            type="primary"
                            @click="
                                pageRef?.showEditModal('添加子权限资源', {
                                    pid: row.id
                                })
                            "
                        ></jb-btn>
                        <jb-btn
                            tip-text="编辑"
                            :icon="Icons.EDIT"
                            type="warning"
                            secondary
                            class="mx-8px"
                            circle
                            @click="
                                pageRef?.showEditModal('修改权限资源', {
                                    id: row.id,
                                    pid: row.pid
                                })
                            "
                        ></jb-btn>
                        <jb-btn
                            tip-text="删除"
                            confirm-text="确认删除该权限吗？"
                            :url="`/api/admin/permission/delete/${row.id}`"
                            :icon="Icons.DELETE"
                            secondary
                            type="error"
                            circle
                            @success="pageRef?.loadData()"
                        ></jb-btn>
                    </template>
                </jb-column>
            </jb-table>
        </template>
    </jb-crud-page>
</template>

<script setup lang="ts">
import { nextTick, ref, watch } from 'vue'
import XEUtils from 'xe-utils'
import { Icons } from '@/constants'
import { JBoltApi } from '@/utils'
import JbCrudPage from '@/components/_builtin/jb-crud-page/index.vue'
import { useResetableData } from '@/hooks/common/use-resetable-data'
import { Model } from '@/typings/api'
import type { DragEndEventArgs } from '@/typings/jbolt.components'
import PermissionEdit from './components/permission-edit/index.vue'
import type { VxeTableInstance } from 'vxe-table'

const pageRef = ref<InstanceType<typeof JbCrudPage> | null>(null)
const tableRef = ref<VxeTableInstance<Model>>()

const filterForm = useResetableData({
    keywords: '',
    moduleId: ''
})
const loading = ref<boolean>(false)
const tableData = ref<Model[]>([])
function handleTableData(data: Model[]) {
    tableData.value = data
    loadingClearTimer = setTimeout(() => {
        loading.value = false
    }, 500)
}

//加载状态清除定时器，因为树形结构渲染有时差，
let loadingClearTimer: NodeJS.Timeout | null = null
function beforeSearch() {
    if (loadingClearTimer != null) {
        clearTimeout(loadingClearTimer)
    }
    loading.value = true
}

/**      排序相关 start             */

const dragable = ref(false)

function handleDragEnd(data: DragEndEventArgs) {
    return JBoltApi.post('/api/admin/permission/changeSortRank', {
        id: data.id,
        oriPid: data.oriPid,
        oriRank: data.oriRank,
        newPid: data.newPid,
        newRank: data.newRank
    }).then(() => {
        return pageRef.value?.loadData()
    })
}

/**    排序相关  end    */

const showData = ref<Model[]>([])
watch(
    () => [filterForm.keywords, filterForm.moduleId, tableData.value],
    XEUtils.debounce(() => {
        search()
    }, 500),
    {
        immediate: true
    }
)
function search() {
    if (!filterForm.keywords && !filterForm.moduleId) {
        showData.value = tableData.value
        return
    }
    const filterVal = XEUtils.toValueString(filterForm.keywords).trim().toLowerCase()
    const filterRE = new RegExp(filterVal, 'gi')
    const options = { children: 'items' }
    const searchProps = ['name', 'url', 'permissionKey']
    const rest = XEUtils.searchTree(
        tableData.value,
        (item) =>
            searchProps.some(
                (key) =>
                    String(item[key]).toLowerCase().indexOf(filterVal) > -1 ||
                    (filterForm.moduleId && item.ofModule == Number(filterForm.moduleId))
            ),
        options
    )
    XEUtils.eachTree(
        rest,
        (item) => {
            searchProps.forEach((key) => {
                if (!item[key]) return
                item[key] = String(item[key]).replace(
                    filterRE,
                    (match) => `<span class="keyword-lighten">${match}</span>`
                )
            })
        },
        options
    )

    // 搜索之后默认展开所有子节点
    nextTick(() => {
        const $table = tableRef.value
        if ($table) {
            $table.setAllTreeExpand(true)
        }
    })
    showData.value = rest
}
</script>

<style scoped lang="scss">
.opentype {
    font-size: 12px;
    color: white;
    padding: 2px 4px;
    border-radius: 4px;
    cursor: default;
}
$bg-colors: (
    type_1: #0000ff,
    type_2: #0080ff,
    type_3: #ff8000,
    type_4: #d79b57,
    type_5: #8a1896,
    type_6: #b51ac3,
    type_7: #329115,
    type_8: #3fbe16,
    type_9: #1b9999,
    type_10: #14bcbc
);

@each $class, $color in $bg-colors {
    .open#{$class} {
        background-color: $color;
    }
}
</style>
